const {loadModule} = window['vue3-sfc-loader'];
import {afterEach, beforeEach} from './each.js';
import config from "../config/index.js";
import userRoutes from '../config/route.js';
import tool from "../utils/tool.js";

const ElNotification = ElementPlus.ElNotification;

// 匹配 views 里面所有的.vue文件
const modules = [
    {path: '/src/views/about/index.vue'},

    {path: '/src/views/home/dashboard/index.vue'},
    {path: '/src/views/home/dashboard/widgets/components/about.vue'},
    {path: '/src/views/home/dashboard/widgets/components/progress.vue'},
    {path: '/src/views/home/dashboard/widgets/components/time.vue'},
    {path: '/src/views/home/dashboard/widgets/components/ver.vue'},
    {path: '/src/views/home/dashboard/widgets/components/welcome.vue'},
    {path: '/src/views/home/dashboard/widgets/index.vue'},
    {path: '/src/views/home/dashboard/work/components/myapp.vue'},
    {path: '/src/views/home/dashboard/work/index.vue'},

    {path: '/src/views/home/userCenter/index.vue'},
    {path: '/src/views/home/userCenter/user/account.vue'},
    {path: '/src/views/home/userCenter/user/logs.vue'},
    {path: '/src/views/home/userCenter/user/password.vue'},
    {path: '/src/views/home/userCenter/user/set.vue'},

    {path: '/src/views/login/components/commonPage.vue'},
    {path: '/src/views/login/components/passwordForm.vue'},
    {path: '/src/views/login/components/phoneForm.vue'},
    {path: '/src/views/login/index.vue'},
    {path: '/src/views/login/resetPassword.vue'},
    {path: '/src/views/login/userRegister.vue'},

    {path: '/src/views/platform/config/index.vue'},
    {path: '/src/views/platform/config/platform.vue'},
    {path: '/src/views/platform/config/system.vue'},
    {path: '/src/views/platform/config/user.vue'},
    {path: '/src/views/platform/dept/index.vue'},
    {path: '/src/views/platform/dict/index.vue'},
    {path: '/src/views/platform/log/index.vue'},
    {path: '/src/views/platform/menu/index.vue'},
    {path: '/src/views/platform/post/index.vue'},
    {path: '/src/views/platform/role/index.vue'},
    {path: '/src/views/platform/tenant/index.vue'},
    {path: '/src/views/platform/user/index.vue'},

    {path: '/src/views/tool/generator/dataSource/index.vue'},
    {path: '/src/views/tool/generator/template/index.vue'},

];

const otherModules = {
    '404': () => Vue.defineAsyncComponent(() => loadModule('/src/layout/other/404.vue', options)),
    'empty': () => Vue.defineAsyncComponent(() => loadModule('/src/layout/other/empty.vue', options)),
}

// 系统路由
const routes = [
    {
        name: "layout",
        path: "/",
        component: () => Vue.defineAsyncComponent(() => loadModule('/src/layout/index.vue', options)),
        redirect: config.DASHBOARD_URL || '/dashboard',
        children: []
    },
    {
        path: "/login",
        component: () => Vue.defineAsyncComponent(() => loadModule('/src/views/login/index.vue', options)),
        meta: {
            title: "登录"
        }
    },
    {
        path: "/user_register",
        component: () => Vue.defineAsyncComponent(() => loadModule('/src/views/login/userRegister.vue', options)),
        meta: {
            title: "注册"
        }
    },
    {
        path: "/reset_password",
        component: () => Vue.defineAsyncComponent(() => loadModule('/src/views/login/resetPassword.vue', options)),
        meta: {
            title: "重置密码"
        }
    }
]

// 系统特殊路由
const routes_404 = {
    path: "/:pathMatch(.*)*",
    hidden: true,
    component: otherModules['404'],
}

let routes_404_r = () => {
}

const router = VueRouter.createRouter({
    history: VueRouter.createWebHashHistory(),
    routes: routes
})

// 设置标题
document.title = config.APP_NAME

// 判断是否已加载过动态 / 静态路由
let isGetRouter = false;

router.beforeEach(async (to, from, next) => {
    NProgress.start()
    // 动态标题
    document.title = to.meta.title ? `${to.meta.title} - ${config.APP_NAME}` : `${config.APP_NAME}`

    let token = tool.data.get("APP_TOKEN");

    if (to.path === "/login") {
        // 删除路由(替换当前layout路由)
        router.addRoute(routes[0])
        // 删除路由(404)
        routes_404_r()
        isGetRouter = false;
        next();
        return false;
    }

    if (routes.findIndex(r => r.path === to.path) >= 0) {
        next();
        return false;
    }

    if (!token) {
        next({
            path: '/login'
        });
        return false;
    }

    // 整页路由处理
    if (to.meta.fullpage) {
        to.matched = [to.matched[to.matched.length - 1]]
    }
    // 加载动态 / 静态路由
    if (!isGetRouter) {
        let apiMenu = tool.data.get("APP_MENU_INFO") || []
        let userInfo = tool.data.get("APP_USER_INFO")
        let userMenu = treeFilter(userRoutes, node => {
            return node.meta.role ? node.meta.role.filter(item => userInfo.role.indexOf(item) > -1).length > 0 : true
        })
        let menu = [...userMenu, ...apiMenu]
        let menuRouter = filterAsyncRouter(menu)
        menuRouter = flatAsyncRoutes(menuRouter)
        menuRouter.forEach(item => {
            router.addRoute("layout", item)
        })
        routes_404_r = router.addRoute(routes_404)
        if (to.matched.length === 0) {
            router.push(to.fullPath);
        }
        isGetRouter = true;
    }
    beforeEach(to, from)
    next();
});

router.afterEach((to, from) => {
    afterEach(to, from)
    NProgress.done()
});

router.onError((error) => {
    NProgress.done();
    ElNotification.error({
        title: '路由错误',
        message: error.message
    });
});

// 追加自定义方法、对象
router.getMenus = () => {
    let apiMenu = tool.data.get("APP_MENU_INFO") || []
    let userInfo = tool.data.get("APP_USER_INFO")
    let userMenu = treeFilter(userRoutes, node => {
        return node.meta.role ? node.meta.role.filter(item => userInfo.role.indexOf(item) > -1).length > 0 : true
    })
    return [...userMenu, ...apiMenu]
}

// 转换
function filterAsyncRouter(routerMap) {
    const accessedRouters = []
    routerMap.forEach(item => {
        item.meta = item.meta ? item.meta : {};
        // 处理外部链接特殊路由
        if (item.meta.type === 'iframe') {
            item.meta.url = item.path;
            item.path = `/i/${item.name}`;
        }
        // MAP 转路由对象
        let route = {
            path: item.path,
            name: item.name,
            meta: item.meta,
            redirect: item.redirect,
            children: item.children ? filterAsyncRouter(item.children) : null,
            component: Vue.defineAsyncComponent(() => loadModule(loadComponent(item.component), options))
        }
        accessedRouters.push(route)
    })
    return accessedRouters
}

function loadComponent(component) {
    if (component) {
        for (let i = 0; i < modules.length; i++) {
            const dir = modules[i].path.split('views/')[1].split('.vue')[0];
            if (dir === component || dir === component + '/index') {
                return modules[i].path;
            }
        }
    }
    return otherModules['empty']
}

// 路由扁平化
function flatAsyncRoutes(routes, breadcrumb = []) {
    let res = []
    routes.forEach(route => {
        const tmp = {...route}
        if (tmp.children) {
            let childrenBreadcrumb = [...breadcrumb]
            childrenBreadcrumb.push(route)
            let tmpRoute = {...route}
            tmpRoute.meta.breadcrumb = childrenBreadcrumb
            delete tmpRoute.children
            res.push(tmpRoute)
            let childrenRoutes = flatAsyncRoutes(tmp.children, childrenBreadcrumb)
            childrenRoutes.map(item => {
                res.push(item)
            })
        } else {
            let tmpBreadcrumb = [...breadcrumb]
            tmpBreadcrumb.push(tmp)
            tmp.meta.breadcrumb = tmpBreadcrumb
            res.push(tmp)
        }
    })
    return res
}

// 过滤树
function treeFilter(tree, func) {
    return tree.map(node => ({...node})).filter(node => {
        node.children = node.children && treeFilter(node.children, func)
        return func(node) || (node.children && node.children.length)
    })
}

export default router
